package com.ershi.spring.aop.proxy.chain;

import com.ershi.spring.aop.proxy.common.TargetMethod;

/**
 * @author 二十
 * @since 2021/10/31 9:58 下午
 */
public abstract class AbstractSlot {

	TargetMethod targetMethod;

	AbstractSlot next;

	abstract Object invoke(TargetMethod targetMethod);

	private boolean hasNextSlot() {
		return next != null;
	}

	public Object proceed(TargetMethod targetMethod) throws Exception {
		return hasNextSlot() ?
				next.invoke(targetMethod) :
				targetMethod.getMethod()
						.invoke(
								targetMethod.getTarget(),
								targetMethod.getArgs()
						);
	}

	public AbstractSlot(TargetMethod targetMethod, AbstractSlot next) {
		this.targetMethod = targetMethod;
		this.next = next;
	}

	public TargetMethod getTargetMethod() {
		return targetMethod;
	}

	public void setTargetMethod(TargetMethod targetMethod) {
		this.targetMethod = targetMethod;
	}

	public AbstractSlot getNext() {
		return next;
	}

	public void setNext(AbstractSlot next) {
		this.next = next;
	}

	public AbstractSlot() {
	}

	public static class Head extends AbstractSlot{

		@Override
		Object invoke(TargetMethod targetMethod) {
			return null;
		}
	}


}
